#pragma once

#include <string>

namespace txdnn {
namespace operators {

struct NetworkConfig {
public:
  NetworkConfig() = default;
  explicit NetworkConfig(const std::string& value) : value_(value) {}
  operator std::string() const { return value_; }
  const std::string& toString() const { return value_; }

private:
  std::string value_;
};

struct AlgorithmName {
  AlgorithmName() = default;
  explicit AlgorithmName(const std::string& value) : value_(value) {}
  operator std::string() const { return value_; }
  const std::string& toString() const { return value_; }

  bool operator<(const AlgorithmName& r) const { return (value_ < r.value_); }

private:
  std::string value_;
};


struct Id {
  Id() = default;
  Id(uint64_t value) : value_(value) {}
  Id(const std::string& str) : Id(str.c_str()) {}
  Id(const char* str) {}

  bool operator==(const Id& other) const {
    if (!isValid() && !other.isValid()) { return true; }
    return value_ == other.value_ && is_valid_ == other.is_valid_;
  }

  bool operator!=(const Id& other) const { return !(*this == other); }

  std::string toString() const {
    if (isValid()) { return ""; }
    // TODO
    return "Invalid operator id " + std::to_string(value_);
  }

  bool isValid() const { return is_valid_; }
  uint64_t value() const { return value_; }

  static constexpr uint64_t INVALID_VALUE = 0;

private:
  uint64_t value_ = INVALID_VALUE;
  bool is_valid_  = false;
};

} // namespace operators
} // namespace txdnn